"use strict";
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
    return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (g && (g = 0, op[0] && (_ = 0)), _) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismaSqlUtils = void 0;
var client_1 = require("@prisma/client");
var prisma = new client_1.PrismaClient();
/**
 * 执行带参数的原生SQL查询（修复参数绑定语法）
 * @param sql 原生SQL语句（使用 ? 作为参数占位符）
 * @param params 参数数组（与SQL中的占位符顺序对应）
 * @returns 查询结果
 */
function executeRawQuery(sql_1) {
    return __awaiter(this, arguments, void 0, function (sql, params) {
        var parts, query, i, result, error_1;
        if (params === void 0) { params = []; }
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    _a.trys.push([0, 2, , 3]);
                    parts = sql.split("?");
                    if (parts.length - 1 !== params.length) {
                        throw new Error("\u53C2\u6570\u6570\u91CF\u4E0D\u5339\u914D\uFF1ASQL\u4E2D\u6709 ".concat(parts.length - 1, " \u4E2A\u5360\u4F4D\u7B26\uFF0C\u5B9E\u9645\u4F20\u5165 ").concat(params.length, " \u4E2A\u53C2\u6570"));
                    }
                    query = client_1.Prisma.raw(parts[0]);
                    for (i = 0; i < params.length; i++) {
                        query = client_1.Prisma.sql(templateObject_1 || (templateObject_1 = __makeTemplateObject(["", " ", " ", ""], ["", " ", " ", ""])), query, params[i], client_1.Prisma.raw(parts[i + 1]));
                    }
                    return [4 /*yield*/, prisma.$queryRaw(query)];
                case 1:
                    result = _a.sent();
                    return [2 /*return*/, result];
                case 2:
                    error_1 = _a.sent();
                    console.error("原生SQL查询失败:", error_1);
                    throw error_1;
                case 3: return [2 /*return*/];
            }
        });
    });
}
/**
 * 执行带参数的原生SQL命令（无返回结果）
 */
function executeRawCommand(sql_1) {
    return __awaiter(this, arguments, void 0, function (sql, params) {
        var parts, query, i, result, error_2;
        if (params === void 0) { params = []; }
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    _a.trys.push([0, 2, , 3]);
                    parts = sql.split("?");
                    if (parts.length - 1 !== params.length) {
                        throw new Error("\u53C2\u6570\u6570\u91CF\u4E0D\u5339\u914D\uFF1ASQL\u4E2D\u6709 ".concat(parts.length - 1, " \u4E2A\u5360\u4F4D\u7B26\uFF0C\u5B9E\u9645\u4F20\u5165 ").concat(params.length, " \u4E2A\u53C2\u6570"));
                    }
                    query = client_1.Prisma.raw(parts[0]);
                    for (i = 0; i < params.length; i++) {
                        query = client_1.Prisma.sql(templateObject_2 || (templateObject_2 = __makeTemplateObject(["", " ", " ", ""], ["", " ", " ", ""])), query, params[i], client_1.Prisma.raw(parts[i + 1]));
                    }
                    return [4 /*yield*/, prisma.$executeRaw(query)];
                case 1:
                    result = _a.sent();
                    return [2 /*return*/, result];
                case 2:
                    error_2 = _a.sent();
                    console.error("原生SQL命令执行失败:", error_2);
                    throw error_2;
                case 3: return [2 /*return*/];
            }
        });
    });
}
/**
 * 替换命名占位符为问号占位符
 * @param sql 包含命名占位符的SQL语句（格式: :name）
 * @param params 包含命名参数的对象
 * @returns 处理后的SQL和参数数组
 */
function replaceNamedPlaceholders(sql, params) {
    var _a;
    var paramNames = Array.from(new Set(((_a = sql.match(/:(\w+)/g)) === null || _a === void 0 ? void 0 : _a.map(function (m) { return m.slice(1); })) || []));
    var paramArray = paramNames.map(function (name) {
        if (params[name] === undefined) {
            throw new Error("\u7F3A\u5C11\u547D\u540D\u53C2\u6570: ".concat(name));
        }
        return params[name];
    });
    var processedSql = sql;
    paramNames.forEach(function (name, index) {
        processedSql = processedSql.replace(new RegExp(":".concat(name, "\\b"), "g"), "?");
    });
    return { sql: processedSql, params: paramArray };
}
/**
 * 统一处理各种参数格式，转为标准格式
 * 支持：数组传参、REST分散传参、命名参数传参
 * @param sql SQL语句
 * @param params 原始参数列表
 * @returns 处理后的SQL和参数数组
 */
function normalizeParams(sql, params) {
    var processedSql = sql;
    var paramArray = [];
    // 情况1：单个数组参数（兼容旧用法）
    if (params.length === 1 && Array.isArray(params[0])) {
        paramArray = params[0];
    }
    // 情况2：最后一个参数是命名参数对象
    else if (params.length > 0 &&
        typeof params[params.length - 1] === "object" &&
        !Array.isArray(params[params.length - 1])) {
        var namedParams = params.pop();
        var result = replaceNamedPlaceholders(sql, namedParams);
        processedSql = result.sql;
        paramArray = __spreadArray(__spreadArray([], params, true), result.params, true);
    }
    // 情况3：REST分散参数
    else {
        paramArray = params;
    }
    // 验证参数数量与占位符匹配
    var placeholderCount = (processedSql.match(/\?/g) || []).length;
    if (placeholderCount !== paramArray.length) {
        throw new Error("\u53C2\u6570\u6570\u91CF\u4E0D\u5339\u914D\uFF1ASQL\u5305\u542B".concat(placeholderCount, "\u4E2A\u5360\u4F4D\u7B26\uFF0C\u4F46\u4F20\u5165\u4E86").concat(paramArray.length, "\u4E2A\u53C2\u6570"));
    }
    return { processedSql: processedSql, paramArray: paramArray };
}
/**
 * 执行带参数的原生SQL查询（返回多条记录）
 * @param sql 原生SQL语句（支持?占位符或命名占位符:name）
 * @param params 参数数组或命名参数对象
 * @returns 查询结果数组
 */
function queryMany(sql) {
    var params = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        params[_i - 1] = arguments[_i];
    }
    return __awaiter(this, void 0, void 0, function () {
        var _a, processedSql, paramArray, parts, query, i, result, error_3;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    _b.trys.push([0, 2, , 3]);
                    _a = normalizeParams(sql, params), processedSql = _a.processedSql, paramArray = _a.paramArray;
                    parts = processedSql.split("?");
                    if (parts.length - 1 !== paramArray.length) {
                        throw new Error("\u53C2\u6570\u6570\u91CF\u4E0D\u5339\u914D\uFF1ASQL\u4E2D\u6709 ".concat(parts.length - 1, " \u4E2A\u5360\u4F4D\u7B26\uFF0C\u5B9E\u9645\u4F20\u5165 ").concat(paramArray.length, " \u4E2A\u53C2\u6570"));
                    }
                    query = client_1.Prisma.raw(parts[0]);
                    for (i = 0; i < paramArray.length; i++) {
                        query = client_1.Prisma.sql(templateObject_3 || (templateObject_3 = __makeTemplateObject(["", " ", " ", ""], ["", " ", " ", ""])), query, paramArray[i], client_1.Prisma.raw(parts[i + 1]));
                    }
                    return [4 /*yield*/, prisma.$queryRaw(query)];
                case 1:
                    result = _b.sent();
                    return [2 /*return*/, result];
                case 2:
                    error_3 = _b.sent();
                    console.error("查询多条记录失败:", error_3);
                    throw error_3;
                case 3: return [2 /*return*/];
            }
        });
    });
}
/**
 * 执行带参数的原生SQL查询（返回单条记录）
 * @param sql 原生SQL语句（支持?占位符或命名占位符:name）
 * @param params 参数数组或命名参数对象
 * @returns 单条查询结果或null
 */
function queryOne(sql) {
    var params = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        params[_i - 1] = arguments[_i];
    }
    return __awaiter(this, void 0, void 0, function () {
        var results;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, queryMany.apply(void 0, __spreadArray([sql], params, false))];
                case 1:
                    results = _a.sent();
                    return [2 /*return*/, results.length > 0 ? results[0] : null];
            }
        });
    });
}
/**
 * 执行更新/删除/插入等SQL命令
 * @param sql 原生SQL语句（支持?占位符或命名占位符:name）
 * @param params 参数数组或命名参数对象
 * @returns 受影响的行数
 */
function executeCommand(sql) {
    var params = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        params[_i - 1] = arguments[_i];
    }
    return __awaiter(this, void 0, void 0, function () {
        var _a, processedSql, paramArray, parts, query, i, result, error_4;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    _b.trys.push([0, 2, , 3]);
                    _a = normalizeParams(sql, params), processedSql = _a.processedSql, paramArray = _a.paramArray;
                    parts = processedSql.split("?");
                    if (parts.length - 1 !== paramArray.length) {
                        throw new Error("\u53C2\u6570\u6570\u91CF\u4E0D\u5339\u914D\uFF1ASQL\u4E2D\u6709 ".concat(parts.length - 1, " \u4E2A\u5360\u4F4D\u7B26\uFF0C\u5B9E\u9645\u4F20\u5165 ").concat(paramArray.length, " \u4E2A\u53C2\u6570"));
                    }
                    query = client_1.Prisma.raw(parts[0]);
                    for (i = 0; i < paramArray.length; i++) {
                        query = client_1.Prisma.sql(templateObject_4 || (templateObject_4 = __makeTemplateObject(["", " ", " ", ""], ["", " ", " ", ""])), query, paramArray[i], client_1.Prisma.raw(parts[i + 1]));
                    }
                    return [4 /*yield*/, prisma.$executeRaw(query)];
                case 1:
                    result = _b.sent();
                    return [2 /*return*/, result];
                case 2:
                    error_4 = _b.sent();
                    console.error("执行SQL命令失败:", error_4);
                    throw error_4;
                case 3: return [2 /*return*/];
            }
        });
    });
}
// 使用示例（注意用 ? 作为占位符）
function testRawQueries() {
    return __awaiter(this, void 0, void 0, function () {
        var users, updatedCount;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, executeRawQuery("SELECT * FROM User WHERE id BETWEEN ? AND ?", // 使用 ? 作为占位符
                    [1, 10])];
                case 1:
                    users = _a.sent();
                    console.log("查询到的用户:", users);
                    return [4 /*yield*/, executeRawCommand("UPDATE Post SET published = ? WHERE authorId = ?", [true, 2])];
                case 2:
                    updatedCount = _a.sent();
                    console.log("\u66F4\u65B0\u4E86 ".concat(updatedCount, " \u6761\u8BB0\u5F55"));
                    return [2 /*return*/];
            }
        });
    });
}
// 使用示例
function testAllScenarios() {
    return __awaiter(this, void 0, void 0, function () {
        var allUsers, filteredUsers, namedParamUsers, firstUser, specificUser, allUnpublished, updatedPosts, namedParamUpdate, insertedUser, deletedUser, specificUserv2, userByRest;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, queryMany("SELECT id, name, email FROM User ORDER BY id ASC")];
                case 1:
                    allUsers = _a.sent();
                    console.log("所有用户:", allUsers);
                    return [4 /*yield*/, queryMany("SELECT id, name FROM User WHERE id BETWEEN ? AND ?", [1, 5])];
                case 2:
                    filteredUsers = _a.sent();
                    console.log("ID在1-5之间的用户:", filteredUsers);
                    return [4 /*yield*/, queryMany("SELECT id, email FROM User WHERE name LIKE :search", { search: "%test%" })];
                case 3:
                    namedParamUsers = _a.sent();
                    console.log("名字包含test的用户:", namedParamUsers);
                    return [4 /*yield*/, queryOne("SELECT * FROM User ORDER BY id ASC LIMIT 1")];
                case 4:
                    firstUser = _a.sent();
                    console.log("第一个用户:", firstUser);
                    return [4 /*yield*/, queryOne("SELECT * FROM User WHERE email = ?", ["alice@example.com"])];
                case 5:
                    specificUser = _a.sent();
                    console.log("指定邮箱的用户:", specificUser);
                    return [4 /*yield*/, executeCommand("UPDATE Post SET published = false")];
                case 6:
                    allUnpublished = _a.sent();
                    console.log("\u5C06\u6240\u6709\u5E16\u5B50\u8BBE\u4E3A\u672A\u53D1\u5E03\uFF0C\u5F71\u54CD\u884C\u6570: ".concat(allUnpublished));
                    return [4 /*yield*/, executeCommand("UPDATE Post SET published = true WHERE authorId = ?", [2])];
                case 7:
                    updatedPosts = _a.sent();
                    console.log("\u66F4\u65B0\u4F5C\u8005ID\u4E3A2\u7684\u5E16\u5B50\uFF0C\u5F71\u54CD\u884C\u6570: ".concat(updatedPosts));
                    return [4 /*yield*/, executeCommand("UPDATE User SET name = :newName WHERE email = :email", { newName: "Updated Name", email: "bob@example.com" })];
                case 8:
                    namedParamUpdate = _a.sent();
                    console.log("\u66F4\u65B0\u6307\u5B9A\u7528\u6237\u7684\u540D\u5B57\uFF0C\u5F71\u54CD\u884C\u6570: ".concat(namedParamUpdate));
                    return [4 /*yield*/, executeCommand("INSERT INTO User (email, name) VALUES (:email, :name)", { email: "temp@example.com", name: "Temporary User" })];
                case 9:
                    insertedUser = _a.sent();
                    console.log("\u63D2\u5165\u65B0\u7528\u6237\uFF0C\u5F71\u54CD\u884C\u6570: ".concat(insertedUser));
                    return [4 /*yield*/, executeCommand("DELETE FROM User WHERE email = ?", [
                            "temp@example.com",
                        ])];
                case 10:
                    deletedUser = _a.sent();
                    console.log("\u5220\u9664\u4E34\u65F6\u7528\u6237\uFF0C\u5F71\u54CD\u884C\u6570: ".concat(deletedUser));
                    return [4 /*yield*/, queryOne("SELECT * FROM User WHERE email = ?", "alice@example.com")];
                case 11:
                    specificUserv2 = _a.sent();
                    console.log("指定邮箱的用户:", specificUserv2);
                    return [4 /*yield*/, queryOne("SELECT * FROM User WHERE email = ?", "example@test.com")];
                case 12:
                    userByRest = _a.sent();
                    console.log("REST参数查询结果:", userByRest);
                    return [2 /*return*/];
            }
        });
    });
}
function main() {
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, prisma.$connect()];
                case 1:
                    _a.sent();
                    //   await testRawQueries();
                    return [4 /*yield*/, testAllScenarios()];
                case 2:
                    //   await testRawQueries();
                    _a.sent();
                    return [2 /*return*/];
            }
        });
    });
}
// main()
//   .catch((e) => console.error("测试失败:", e))
//   .finally(async () => {
//     await prisma.$disconnect();
//   });
var RawSqlUtils = {
    executeRawQuery: executeRawQuery,
    executeRawCommand: executeRawCommand,
    queryMany: queryMany,
    queryOne: queryOne,
    executeCommand: executeCommand,
};
// 关键修改：以对象形式导出，方便JS中通过 XX.func 调用
exports.PrismaSqlUtils = {
    executeRawQuery: executeRawQuery,
    executeRawCommand: executeRawCommand,
    queryMany: queryMany,
    queryOne: queryOne,
    executeCommand: executeCommand,
};
var templateObject_1, templateObject_2, templateObject_3, templateObject_4;
